package fr.geobert.prediction;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.AutoCompleteTextView;

/**
 * I use AutoCompleteTextView to let Android manage the call to SQL for
 * integration with another TextView, keep the onTextChanged method and an
 * equivalent to replaceText
 * 
 * after reading this file, read MatchAdapter
 * 
 */
public class MyAutoCompleteTextView extends AutoCompleteTextView {
	public static String TAG = "Prediction";
	int position; // position in sentence, start at 0
	long parent_id; // parent word _id
	StringBuilder currentWord;
	protected long selectedWord; // _id of last selected word in prediction

	public MyAutoCompleteTextView(Context context) {
		super(context);
		init();
	}

	public MyAutoCompleteTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public MyAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	private void init() {
		selectedWord = 0;
		position = 0;
		parent_id = 0;
		currentWord = new StringBuilder();
	}

	// I tried to do an incremental parser to avoid parsing the whole text each
	// time but I have many issues with the start, before and after parameters
	// not right after insertion by prediction, see replaceText() below
	@Override
	protected void onTextChanged(CharSequence text, int start, int before, int after) {
		Log.d(TAG,
				"onTextChanged [" + text + "]" + start + ":" + before + ":" + after + "/"
						+ text.length());
		super.onTextChanged(text, start, before, after);

		// trim the string to make blank string == empty string
		if (text.toString().trim().length() != 0) {
			if (before < after) { // inserted text
				Log.d(TAG, "onTextChanged inserted text ");

				// get the changed text
				CharSequence addedText = text.subSequence(start, text.length());
				Log.d(TAG, "onTextChanged addedText [" + addedText + "]");

				// parse the added text
				for (int i = 0; i < addedText.length(); ++i) {
					Log.d(TAG, "onTextChanged char [" + addedText.charAt(i) + "]");

					// check end of sentence
					if (LangDbAdapter.sentence_separator.indexOf(addedText.charAt(i)) > -1) {
						Log.d(TAG, "onTextChanged sentence end, reset position and current word ["
								+ currentWord + "]");
						position = 0;
						currentWord.setLength(0);
						break;
					} else if (LangDbAdapter.word_separator.indexOf(addedText.charAt(i)) > -1) {
						// new word -> increment position in sentence, reset
						// current word and set parent_id

						// TODO manage case of multiple consecutive
						// word_separator
						Log.d(TAG, "onTextChanged increment position, reset current word ");
						position++;
						if (selectedWord != 0) { // a word was selected, use it
													// as parent
							parent_id = selectedWord;
							selectedWord = 0;
						} else { // no selection, try to find its _id in DB
							parent_id = LangDbAdapter.getInstance((Activity) getContext())
									.getParentId(currentWord.toString());
						}
						currentWord.setLength(0);
						break;
					}
					currentWord.append(addedText.charAt(i));
				}
			} else {
				// TODO manage deletion of letters
				// TODO manage modified text
			}
		}
		Log.d(TAG, "onTextChanged currentWord " + currentWord);
		Log.d(TAG, "onTextChanged position " + position);
		Log.d(TAG, "onTextChanged parent_id " + parent_id);
		MatchAdapter adap = (MatchAdapter) getAdapter();
		if (null != adap) {
			adap.position = position;
			adap.parentId = parent_id;
			adap.mCurrentWord = currentWord.toString();
		}

		// after this android call MatchAdapter.runQueryOnBackgroundThread which
		// run LangDbAdapter.fetchMatchingInfo
	}

	// called to predict first word
	public void initialFiltering() {
		MatchAdapter adap = (MatchAdapter) getAdapter();
		if (null != adap) {
			adap.position = position;
			adap.parentId = parent_id;
			adap.mCurrentWord = currentWord.toString();
		}
		performFiltering("", 0);
	}

	// AutoCompleteTextView specific
	@Override
	public boolean enoughToFilter() {
		return true;
	}

	// need a control on inserting word in order to have the good start, before
	// and end parameters in onTextChanged, I tried to get the parameters to be
	// like start == before when text is inserted (as said in android doc) but I
	// failed
	@Override
	protected void replaceText(CharSequence text) {
		if (getText().length() == 0) {
			super.replaceText(text);
		} else {
			String curTxt = getText().toString();
			int idx = curTxt.lastIndexOf(' '); // TODO I look for space only,
												// but we need to look for the
												// lastIndexOf(word_separators)
			if (idx > -1) {
				getEditableText().replace(idx + 1, getText().length(), text);
			} else if (position == 0) {
				super.replaceText(text);
			}
			// set Cursor to end of text, maybe not the behavior you want
			setSelection(getText().length());
		}
	}
}
